-- xmake.lua for STM32G431 PCAN-FD Project

set_project("pcanfd")
set_version("1.0.0")

-- Add debug mode
add_rules("mode.debug", "mode.release")

target("pcanfd")
    set_kind("binary")
    set_filename("pcanfd.elf")
    
    -- Set platform and architecture for STM32G431
    set_plat("cross")
    set_arch("cortex-m4")
    
    -- Disable automatic flag detection to prevent conflicts
    set_policy("check.auto_ignore_flags", false)
    
    -- STM32G431 specific compiler flags
    add_cflags("-mcpu=cortex-m4", "-mthumb", "-mfpu=fpv4-sp-d16", "-mfloat-abi=hard")
    add_cflags("-DUSE_HAL_DRIVER", "-DSTM32G431xx", "-DPCAN_PRO_FD")
    add_cflags("-Wall", "-fdata-sections", "-ffunction-sections")
    
    -- Debug and release specific flags
    if is_mode("debug") then
        add_cflags("-O0", "-g3", "-gdwarf-2")
        add_cflags("-fno-omit-frame-pointer")
        add_cflags("-DDEBUG")
    else
        add_cflags("-O2", "-g0")
        add_cflags("-DNDEBUG")
    end
    
    -- Linker flags
    add_ldflags("-mcpu=cortex-m4", "-mthumb", "-mfpu=fpv4-sp-d16", "-mfloat-abi=hard")
    add_ldflags("-specs=nano.specs", "-TSTM32G431C8TX_FLASH.ld")
    add_ldflags("-Wl,--gc-sections", "-Wl,-Map=$(buildir)/pcanfd.map,--cref")
    add_ldflags("-Wl,--no-warn-rwx-segments")  -- Suppress warnings about segments
    
    -- Assembly flags
    add_asflags("-mcpu=cortex-m4", "-mthumb", "-mfpu=fpv4-sp-d16", "-mfloat-abi=hard")
    if is_mode("debug") then
        add_asflags("-g3", "-gdwarf-2")
    end
    
    -- Include directories
    add_includedirs("Core/Inc")
    add_includedirs("Core/User")
    add_includedirs("Drivers/STM32G4xx_HAL_Driver/Inc")
    add_includedirs("Drivers/STM32G4xx_HAL_Driver/Inc/Legacy")
    add_includedirs("Drivers/CMSIS/Device/ST/STM32G4xx/Include")
    add_includedirs("Drivers/CMSIS/Include")
    add_includedirs("USB_Device/App")
    add_includedirs("USB_Device/Target")
    add_includedirs("Middlewares/ST/STM32_USB_Device_Library/Core/Inc")
    
    -- Source files
    -- Core source files
    add_files("Core/Src/main.c")
    add_files("Core/Src/stm32g4xx_hal_msp.c")
    add_files("Core/Src/stm32g4xx_it.c")
    add_files("Core/Src/system_stm32g4xx.c")
    add_files("Core/Src/syscalls.c")
    add_files("Core/Src/sysmem.c")
    
    -- User source files
    add_files("Core/User/can.c")
    add_files("Core/User/log.c")
    add_files("Core/User/pcanpro_fd_protocol.c")
    add_files("Core/User/pcanpro_led.c")
    add_files("Core/User/pcanpro_timestamp.c")
    add_files("Core/User/pcanpro_usbd.c")
    add_files("Core/User/system.c")
    add_files("Core/User/util_ringbuffer.c")
    add_files("Core/User/util_tfp.c")
    
    -- USB Device source files
    add_files("USB_Device/App/usb_device.c")
    add_files("USB_Device/App/usbd_desc.c")
    add_files("USB_Device/Target/usbd_conf.c")
    
    -- STM32 HAL Driver source files
    add_files("Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal.c")
    add_files("Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_cortex.c")
    add_files("Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_dma.c")
    add_files("Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_dma_ex.c")
    add_files("Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_exti.c")
    add_files("Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_fdcan.c")
    add_files("Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_flash.c")
    add_files("Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_flash_ex.c")
    add_files("Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_flash_ramfunc.c")
    add_files("Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_gpio.c")
    add_files("Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_pcd.c")
    add_files("Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_pcd_ex.c")
    add_files("Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_pwr.c")
    add_files("Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_pwr_ex.c")
    add_files("Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_rcc.c")
    add_files("Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_rcc_ex.c")
    add_files("Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_uart.c")
    add_files("Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_uart_ex.c")
    add_files("Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_ll_usb.c")
    
    -- USB Device Library source files
    add_files("Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c")
    add_files("Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c")
    add_files("Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c")
    
    -- Startup file
    add_files("Core/Startup/startup_stm32g431c8tx.s")
    
    -- Post build actions to generate hex and bin files
    after_build(function (target)
        local elf = target:targetfile()
        local hex = path.join(target:targetdir(), "pcanfd.hex")
        local bin = path.join(target:targetdir(), "pcanfd.bin")
        
        os.vrun("arm-none-eabi-objcopy -O ihex " .. elf .. " " .. hex)
        os.vrun("arm-none-eabi-objcopy -O binary -S " .. elf .. " " .. bin)
        
        -- Generate listing file for debugging
        if is_mode("debug") then
            local lst = path.join(target:targetdir(), "pcanfd.lst")
            local map = path.join(target:targetdir(), "pcanfd.map")
            local symbols = path.join(target:targetdir(), "pcanfd.symbols")
            
            os.vrun("arm-none-eabi-objdump -S " .. elf .. " > " .. lst)
            os.vrun("arm-none-eabi-nm " .. elf .. " > " .. symbols)
        end
        
        local size = os.iorun("arm-none-eabi-size " .. elf)
        print(size)
    end)